﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using BrainTechLLC;
using BrainTechLLC.WPF;

namespace BrainTechLLC.WPF
{
    public static class UtilWPF
    {
        public static Point EmptyPoint = new Point(-1.99D, -1.99D);

        public static Visibility GetVisibility(this bool b) { return b ? Visibility.Visible : Visibility.Collapsed; }

        public static bool WithinWidthHeightTolerance(double width, double height, double oldWidth, double oldHeight)
        {
            double widthDifference = Math.Abs(oldWidth - width);
            double heightDifference = Math.Abs(oldHeight - height);

            return (widthDifference <= 8D && heightDifference <= 8D);
        }

        public static bool WithinBounds(this double val, double low, double high)
        {
            return (val >= low && val <= high);
        }

        public static void GetScrollViewerInfo(this ScrollViewer scrollViewer, out double viewportWidth, out double viewportHeight, out double verticalOffset)
        {
            viewportWidth = double.MaxValue;
            viewportHeight = double.MaxValue;
            verticalOffset = 0D;

            if (scrollViewer != null)
            {
                viewportWidth = scrollViewer.ViewportWidth;
                viewportHeight = scrollViewer.ViewportHeight;
                verticalOffset = scrollViewer.VerticalOffset;
            }
        }

#if SILVERLIGHT
#else
        /// <summary>
        /// Gets the location of the dependency object relative to the scroll viewer
        /// </summary>
        /// <param name="dep"></param>
        /// <param name="scrollViewer"></param>
        /// <returns></returns>
        public static Point GetLocation(this DependencyObject dep, ScrollViewer scrollViewer)
        {
            if (scrollViewer == null)
                scrollViewer = (dep as FrameworkElement).FindParent<ScrollViewer>();

            System.Windows.Point p = new System.Windows.Point(0, 0);

            if (scrollViewer != null)
            {
                try
                {
                    GeneralTransform gt = (dep as Visual).TransformToVisual(scrollViewer);
                    p = gt.Transform(new System.Windows.Point(0, 0));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    return EmptyPoint;
                }
            }

            return p;
        }

        public static bool? GetIsVisibleInScroller(this DependencyObject dep, ScrollViewer scrollViewer, double viewportWidth, double viewportHeight, double verticalOffset)
        {
            if (scrollViewer == null)
                scrollViewer = (dep as FrameworkElement).FindParent<ScrollViewer>();

            System.Windows.Point p = new System.Windows.Point(0, 0);

            if (scrollViewer != null)
            {
                try
                {
                    GeneralTransform gt = (dep as Visual).TransformToVisual(scrollViewer);
                    p = gt.Transform(new System.Windows.Point(0, 0));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    Thread.Sleep(100);
                    return null;
                }
            }

            double thisActualHeight = (double)dep.GetValue(Control.ActualHeightProperty);

            if (p.Y + thisActualHeight >= 0)
            {
                return (p.X < viewportWidth && (p.Y + thisActualHeight + 16D) >= 0 && (p.Y - 10D) <= viewportHeight);
            }
            return false;
        }
#endif

        #if SILVERLIGHT
#else

        public static string CalculateMD5Hash(this byte[] bytes)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(bytes);
            ASCIIEncoding enc = new ASCIIEncoding();
            return enc.GetString(retVal);
        }
#endif

        public static List<T> GetSelected<T>(this ListBox listBox) where T : class
        {
            List<T> results = new List<T>();

            if (listBox == null || listBox.SelectedItems == null)
                return results;

            foreach (var item in listBox.SelectedItems)
            {
                var vm = item as T;
                results.Add(vm);
            }

            return results;
        }
    }
}
